package com.hxzf.mvp.web.controller;

import com.hxzf.mvp.commons.BaseController;
import com.hxzf.mvp.commons.domain.Resp;
import com.hxzf.mvp.dao.entity.User;
import com.hxzf.mvp.service.UserService;
import com.hxzf.mvp.service.converter.UserConverter;
import com.hxzf.mvp.service.dto.UserDto;
import com.hxzf.mvp.service.dto.UserEdit;
import com.hxzf.mvp.service.dto.UserQuery;
import com.hxzf.mvp.service.impl.UserServiceImpl;
import com.iakuil.toolkit.BeanUtils;
import com.iakuil.toolkit.PasswordHash;
import io.swagger.annotations.*;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
 * 用户管理接口
 *
 * <p>复杂的业务接口不应该依赖代码生成器。
 *
 * @author Kai
 * @date 2021/6/21 17:42
 **/
@Api(value = "UserController", tags = {"用户管理"})
@RestController
@RequestMapping("/user/")
public class UserController extends BaseController {

    private final UserService userService;

    private final UserConverter userConverter;

    public UserController(UserServiceImpl userService, UserConverter userConverter) {
        this.userService = userService;
        this.userConverter = userConverter;
    }

    @ApiOperation(value = "用户详情", notes = "根据ID查询用户详情。")
    @ApiImplicitParam(name = "id", value = "实体ID", required = true, dataType = "long", paramType = "path")
    @GetMapping(value = "/{id}")
    public Resp<UserDto> queryDetails(@PathVariable Long id) {
        return ok(userConverter.toDto(userService.getById(id)));
    }

    @ApiOperation(value = "用户列表", notes = "分页查询用户列表。")
    @PostMapping(value = "/list")
    public Resp<UserDto> doQuery(@Valid @RequestBody UserQuery userQuery) {
        // 使用mapstruct将Dto与Entity转换逻辑分离出来
        return page(userService.list(BeanUtils.copy(userQuery, User.class))).map(UserConverter.INSTANCE::toDto);
    }

    @ApiOperation(value = "用户新增", notes = "新增用户。")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用户名", required = true, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "密码", required = true, dataType = "String", paramType = "query")
    })
    @PostMapping(value = "/add")
    public Resp<?> doAdd(@RequestParam String username, @RequestParam String password) {
        User entity = new User();
        entity.setUsername(username);
        if (userService.exists(entity)) {
            return fail("用户名已存在！");
        }

        entity.setPassword(PasswordHash.createHash(password));
        return ok(userService.save(entity));
    }

    @ApiOperation(value = "信息变更", notes = "修改用户信息。")
    @PostMapping(value = "/edit")
    public Resp<?> doChange(@ApiParam(value = "用户信息", required = true) @Valid @RequestBody UserEdit param) {
        // 这种简单的场景就不需要mapstruct出马了
        return ok(userService.modify(BeanUtils.copy(param, User.class)));
    }

    @ApiOperation(value = "用户删除", notes = "删除用户。")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户ID，多个以逗号分隔", required = true, dataType = "String", paramType = "query")
    })
    @PostMapping(value = "/remove")
    public Resp<?> doRemove(@RequestParam Long id) {
        // 这个位置可以做一些简单的校验
        if (!userService.exists(id)) {
            return fail("无效的ID！");
        }
        return ok(userService.remove(id));
    }

    @ApiOperation(value = "复杂查询", notes = "演示复杂单表查询。这个复杂是相对的，不能使用BaseService中查询方法的我们就叫它复杂查询。")
    @PostMapping(value = "/query")
    public Resp<UserDto> doQueryByMpWrapper(@RequestBody UserQuery query) {
        return page(userService.findByCondition(query)).map(item -> BeanUtils.copy(item, UserDto.class));
    }

    @ApiOperation(value = "原生查询", notes = "演示Mybatis原生查询。")
    @PostMapping(value = "/query2")
    public Resp<UserDto> doQueryByNativeSql(@RequestBody UserQuery query) {
        return page(userService.findByCondition2(query)).map(item -> BeanUtils.copy(item, UserDto.class));
    }
}
